package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.utils.HttpUtil;
import com.sky.constant.MessageConstant;
import com.sky.dto.UserLoginDTO;
import com.sky.entity.User;
import com.sky.exception.LoginFailedException;
import com.sky.mapper.UserMapper;
import com.sky.properties.WeChatProperties;
import com.sky.service.UserService;
import com.sky.utils.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";

    @Autowired
    private WeChatProperties weChatProperties;

    @Autowired
    private UserMapper userMapper;

    /*
    * 微信登录
    *  */
    public User wxLogin(UserLoginDTO userLoginDTO) {
        String openid = getOpenid(userLoginDTO.getCode());
        // 判断openid是否为空，如果为空表示登录失败，抛出业务异常
        if(openid == null) {
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        // 判断当前用户是否为新用户
        User user = userMapper.getByOpenid(openid);
        // 如果是新用户，自动完成注册
        if(user == null) {
            user = User.builder()
                .openid(openid)
                .createTime(LocalDateTime.now())
                .build();
            userMapper.insert(user);
        }

        return user;
    }

    /* 
    * 调用微信接口服务，获取微信用户的openid
    *  */
    private String getOpenid(String code) {
        // 调用微信接口服务，获取当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN, map);

        JSONObject jsonObject = JSON.parseObject(json);
        return jsonObject.getString("openid");
    }

    /*
     * 导出用户xlsx表
     *  */
    public void exportUser(LocalDateTime startTime, LocalDateTime endTime, HttpServletResponse response) {
        // 1.查询数据库，获取用户数据
        List<User> users = userMapper.list(startTime, endTime);
        // 2.通过POI将数据写入到Excel文件中
        try (
                InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/userTemplate.xlsx");
        ) {
            if (in != null) {
                // 基于模板文件创建一个新的Excel文件
                XSSFWorkbook excel = new XSSFWorkbook(in);
                // 获取表格文件的sheet页
                int activeSheetIndex = excel.getActiveSheetIndex();
                XSSFSheet sheet = excel.getSheetAt(activeSheetIndex);
                // 填充数据
                int lastRowNum = sheet.getLastRowNum();
                for (int i = 0; i < users.size(); i++) {
                    XSSFRow row = sheet.createRow(lastRowNum + 1 + i);
                    row.createCell(0).setCellValue(users.get(i).getId());
                    row.createCell(1).setCellValue(users.get(i).getOpenid());
                    row.createCell(2).setCellValue(users.get(i).getName());
                    row.createCell(3).setCellValue(users.get(i).getPhone());
                    row.createCell(4).setCellValue(users.get(i).getSex());
                    row.createCell(5).setCellValue(users.get(i).getIdNumber());
                    row.createCell(6).setCellValue(users.get(i).getAvatar());
                    row.createCell(7).setCellValue(String.valueOf(users.get(i).getCreateTime()));
                }
                // 通过输出流将excel文件下载到客户端浏览器
                ServletOutputStream out = response.getOutputStream();
                //清空缓存
                response.reset();
                //定义浏览器响应表头，顺带定义下载名，比如students(中文名需要转义)
                String fileName = "excel文件导出测试";
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls");
                //定义下载的类型，标明是excel文件
                response.setContentType("application/vnd.ms-excel");
                excel.write(out);

                excel.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
